<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Zego Express Video Call</title>
    <!-- 此处需要改成正确的 SDK 版本号 -->
    <script src="./dist_js/ZegoExpressWebRTC-2.12.3.js"></script>
    <script src="./jquery.min.js"></script>
    <script type="text/javascript" src="token_util/crypto-js.min.js"></script>
    <script type="text/javascript" src="token_util/token.js"></script>
    <style type="text/css">
        video::-webkit-media-controls-timeline {
            display: none;
        }

        video::-webkit-media-controls-volume-slider {
            display: none;
        }

        video::-webkit-media-controls-current-time-display {
            display: none;
        }

        video::-webkit-media-controls-time-remaining-display {
            display: none;
        }
        video {
            width: 280px;
        }
    </style>
</head>

<body style="padding-left: 200px;padding-top: 50px;">
    <div>AppID <span style="font-size: 12px;color: grey;margin-left: 8px;"><a href="https://console.zego.im"
                target="_blank">即构控制台</a>>概览>我的项目>查看>AppID</span></div>
    <input style="margin-bottom: 12px;width: 400px;" type="text" name="AppID" id="AppID" value=""
        placeholder="填写你的项目的AppID，从控制台获取"><br>
    <div>ServerSecret <span style="font-size: 12px;color: grey;margin-left: 8px;"><a href="https://console.zego.im"
                target="_blank">即构控制台</a>>概览>我的项目>查看>ServerSecret</span></div>
    <input style="margin-bottom: 12px;width: 400px;" type="text" name="ServerSecret" id="ServerSecret" value=""
        placeholder="填写你的项目的ServerSecret，从控制台获取"><br>

    <div>
        <span>UserID</span><span style="font-size: small;color:grey;"> 由开发者定义，一个用户对应一个唯一的 userID</span>
    </div>
    <input style="margin-bottom: 12px;" required="required" type="text" name="UserID" id="UserID" value=""
        oninput="onUserIDChange()">

    <div><span>RoomID</span><span style="font-size: small;color:grey;"> 由开发者定义，用户在同一房间里才能进行视频通话</span></div>
    <input style="margin-bottom: 12px;" required="required" type="text" name="RoomID" id="RoomID" value="room1">

    <br>
    <button style="width: 200px;color: blue;" type="submit" onclick="onClickLogin()">登录</button>
    <button style="width: 200px; color: crimson;" type="submit" onclick="onClickLogout()">退出</button>
    <br>
    <span style="font-size: small;color:grey;"> 在本页面中，登录后会自动推送音视频（推流），退出后停止推送音视频</span>
    <div style="background-color: aliceblue;color: #f97885fc;font-size: 12px;margin-top: 12px;width: fit-content;"
        id="RoomStatus">房间未连接</div>
    <span style="font-size: 12px;margin-top: 12px;width: fit-content;color: rgb(159, 158, 158);"
        id="RoomUserUpdate"></span>

    <h2>
        基础视频通话
    </h2>
    <div><span>Publish StreamID</span><span style="font-size: small;color:grey;"> 本地推送的音视频流的 streamID，在这个 demo 中我们设置为和
            userID
            一样，实际开发过程中可以更改</span></div>
    <input type="text" name="StreamID" id="StreamID" value="user1">

    <div style="margin-top: 20px;">本地用户（我）的视频： <span
            style="background-color: aliceblue;color: #f97885fc;font-size: 12px;margin-top: 12px;width: fit-content;"
            id="PublishStatus">未推送音视频流</span></div>
    <video style="height: 200px;width: 300px;" id="local-video" autoplay muted playsinline controls></video>
    <div id="remotestreamID"></div>
    <div id="remoteCon"></div>
    <hr style="margin-top: 30px;margin-bottom: 20px;">
    <h2>
        拉取指定 StreamID 的音视频流
    </h2>

    <span>Playing StreamID</span>
    <input type="text" name="StreamID" id="SomeStreamID" value=""> <br><br>
    <button style="width: 200px;color: blue;display: block;" type="submit"
        onclick="onClickPlayingStream()">拉流播放</button>
    <button style="width: 200px;color: red;display: block;" type="submit"
        onclick="onClickStopPlayingStream()">停止拉流</button>
    <br> <br>

    <video id="somevideo" autoplay muted playsinline controls></video>
    <script>
        var appID;
        var serverSecret;

        var server = "wss://webliveroom" + appID + "-api.imzego.com/ws";
        // 初始化实例
        var zg;

        var saved_appID = localStorage.getItem("AppID")
        var saved_serverSecret = localStorage.getItem("ServerSecret")
        var saved_userID = `user_${Math.ceil(Math.random() * 1000)}`;
        $("#AppID").val(saved_appID);
        $("#ServerSecret").val(saved_serverSecret);
        $("#UserID").val(saved_userID);
        $("#StreamID").val(saved_userID);
        

        function onUserIDChange() {
            const value = $("#UserID").val();
            $("#StreamID").val(value);
        }
        function onClickLogout() {
            zg.logoutRoom();
            var streamID = $("#SomeStreamID").val();
            zg.stopPlayingStream(streamID);
            const remoteVideo = document.getElementById('local-video');
            remoteVideo.srcObject = null;
            $("#PublishStatus").text('未推送音视频流');
            $("#RoomUserUpdate").text('');
            $("#remotestreamID").text('');
            document.querySelector("#remoteCon").innerHTML = ""

        }

        function onClickPublishingStream() {
            // 创建流、预览
            // 调用 createStream 接口后，需要等待 ZEGO 服务器返回流媒体对象才能执行后续操作
            zg.createStream().then(localStream => {
                // 获取页面的 video 标签
                const localVideo = document.getElementById('local-video');
                // stream 为MediaStream对象，开发者可通过赋值给video或audio的srcObject属性进行渲染
                localVideo.srcObject = localStream;
                // 开始推流，将自己的音视频流推送到 ZEGO 音视频云，此处 streamID 由用户定义，需全局唯一
                let streamID = $("#StreamID").val();
                zg.startPublishingStream(streamID, localStream)
            });

        }

        function onClickPlayingStream() {
            var streamID = $("#SomeStreamID").val();
            zg.startPlayingStream(streamID).then(remoteStream => {
                const remoteVideo = document.getElementById('somevideo');
                remoteVideo.srcObject = remoteStream;
            }).catch(result => {
                debugger
                if (result['code'] != 0) {
                    alert(result['message']);
                }
            });

        }
        function onClickStopPlayingStream() {
            var streamID = $("#SomeStreamID").val();
            zg.stopPlayingStream(streamID);
            const remoteVideo = document.getElementById('somevideo');
            remoteVideo.srcObject = null;
        }

        function onClickLogin() {
            appID = document.getElementById("AppID").value;
            serverSecret = document.getElementById("ServerSecret").value;
            if (appID == '') {
                alert('AppID 不能为空，请从控制台获取 AppID 粘贴到此处'); return;
            }
            if (serverSecret == '') {
                alert('ServerSecret 不能为空，请从控制台获取 ServerSecret 粘贴到此处'); return;
            }
            server = "wss://webliveroom" + appID + "-api.imzego.com/ws";
            zg = new ZegoExpressEngine(Number(appID), server);

            var roomID = document.getElementById("RoomID").value; // roomID 用户自己设置，必须保证全局唯一
            var userID = document.getElementById("UserID").value;
            var userName = document.getElementById("UserID").value;// userName 用户自己设置，没有唯一性要求
            if (roomID == '') {
                alert('roomID 不能为空，请填写一个roomID，如 room1'); return;
            }
            if (userID == '') {
                alert('userID 不能为空，请填写一个 userID，如 user1'); return;
            }
            var token = generateToken(+appID, serverSecret, userID, 36000);
        
            zg.loginRoom(roomID, token, { userID, userName: userName }, { userUpdate: true }).then(result => {
                if (result == true) {
                    console.log("login success");
                    $("#RoomUserUpdate").text('');
                    alert("登录成功")
                    zg.createStream().then(localStream => {
                        const localVideo = document.getElementById('local-video');
                        localVideo.srcObject = localStream;
                        let streamID = $("#StreamID").val();
                        zg.startPublishingStream(streamID, localStream)
                    });

                } else {
                    alert("登录失败, 错误信息：", result)
                }
            }).catch(err => {
                $("#RoomUserUpdate").text('');
                alert("登录失败: ", +err)
            });

            localStorage.setItem("AppID", appID)
            localStorage.setItem("ServerSecret", serverSecret)
            localStorage.setItem("UserID", userID)

            // 房间状态更新回调
            // 此处在登录房间成功后，立即进行推流。在实现具体业务时，您可选择其他时机进行推流，只要保证当前房间连接状态是连接成功的即可。
            // 房间状态更新回调
            zg.on('roomStateUpdate', async (roomID, state, errorCode, extendedData) => {
                if (state == 'CONNECTED') {
                    $("#RoomStatus").text('房间连接成功');
                } else if (state == 'DISCONNECTED') {
                    $("#RoomStatus").text('房间已断开');
                    $("#RoomUserUpdate").text('');
                } else if (state == 'CONNECTING') {
                    $("#RoomStatus").text('房间连接中');
                }
            })

            zg.on('roomUserUpdate', (roomID, updateType, userList) => {
                // 其他用户进出房间的通知
                if (updateType == 'ADD') {
                    $("#RoomUserUpdate").text(`用户 ${userList[0]['userID']} 加入了房间`);
                } else if (updateType == 'DELETE') {
                    $("#RoomUserUpdate").text(`用户 ${userList[0]['userID']} 退出了房间`);
                }


            });

            zg.on('publisherStateUpdate', result => {
                // 推流状态更新回调
                var state = result['state']
                var streamID = result['streamID']
                var errorCode = result['errorCode']
                var extendedData = result['extendedData']
                if (state == 'PUBLISHING') {
                    $("#PublishStatus").text('成功推送音视频');
                } else if (state == 'NO_PUBLISH') {
                    $("#PublishStatus").text('未推送音视频流');
                } else if (state == 'PUBLISH_REQUESTING') {
                    $("#PublishStatus").text('请求推送音视频流');
                }
            })

            zg.on('playerStateUpdate', result => {
                // 拉流状态更新回调
                // ...
            })

            zg.on('IMRecvBroadcastMessage', (roomID, chatData) => {
                console.log('广播消息IMRecvBroadcastMessage', roomID, chatData[0].message);
                alert(chatData[0].message)
            });
            zg.on('IMRecvBarrageMessage', (roomID, chatData) => {
                console.log('弹幕消息IMRecvBroadcastMessage', roomID, chatData[0].message);
                alert(chatData[0].message)
            });

            zg.on('IMRecvCustomCommand', (roomID, fromUser, command) => {
                console.log('自定义消息IMRecvCustomCommand', roomID, fromUser, command);
                alert(command)
            });

            zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {

                if (updateType === "ADD") {
                    streamList.forEach((stream) => {
                        // 拉流渲染
                        startPlay(stream.streamID)
                    })
                } else {
                    streamList.forEach((stream) => {
                        // 拉流删除
                        deletePlayer(stream.streamID)
                    })
                }
            });
        }

        async function startPlay(streamID) {
            const stream = await zg.startPlayingStream(streamID)
            const video = document.createElement("video")
            video.id = streamID
            video.autoplay = true
            video.muted = true
            video.controls = true
            video.playsinline = true
            document.querySelector("#remoteCon").appendChild(video)

            $("#remotestreamID").text('房间内其他用户的视频流：');

            video.srcObject = stream
        }

        async function deletePlayer(streamID) {
            await zg.stopPlayingStream(streamID)
            document.querySelector(`#${streamID}`).remove()
        }

        function toast(msg, duration) {
            duration = isNaN(duration) ? 3000 : duration;
            var m = document.createElement('div');
            m.innerHTML = msg;
            m.style.cssText = "width: 300px;min-width: 150px;opacity: 0.7;height: 30px;color: rgb(255, 255, 255);line-height: 30px;text-align: center;border-radius: 5px;position: fixed;top: 40%;left: 20%;z-index: 999999;background: rgb(0, 0, 0);font-size: 12px;";
            document.body.appendChild(m);
            setTimeout(function () {
                var d = 0.5;
                m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
                m.style.opacity = '0';
                setTimeout(function () { document.body.removeChild(m) }, d * 1000);
            }, duration);
        }
    </script>
</body>

</html>